#include "converter.h"

Converter::Converter(const wxString& txtpath, const wxString& dictpath) :
_txtfile(txtpath, _T("rb")), _dictdb_utils(dictpath) {
    _converted_words = 0;
    d_id = -1;
    
    _dictdb_utils.mk_tables();
    _dictdb_utils.mk_indexes();
    
    _dictdb_utils.begin();
}

bool Converter::start() {
    _set_dict_info();
    
    wxPrintf( _T(
            "\nBookname: %s\n"
            "Author: %s\n"
            "Email: %s\n"
            "Website: %s\n"
            "Version: %s\n"
            "License: %s\n"
            "Description: %s\n"
            "Original Language: %s\n"
            "Destination Language: %s\n")
            , dictname.c_str()
            , author.c_str()
            , email.c_str()
            , website.c_str()
            , version.c_str()
            , license.c_str()
            , description.c_str()
            , origLang.c_str()
            , destLang.c_str());
    
    wxString line;
    
    int ret = 0;
    while( ret != -1 ) {
        ret = _read_line(line);
        
        if (1==ret) { // empty line
            continue;
        } 
        
        if (0==ret) { // info line
            if (_converted_words%100== 1) {
                wxPrintf(_T("."));
                fflush(stdout);
            }
            
            _converted_words++;
            _add_word_to_dictdb(line);
        }
    }
    
    wxPrintf(_T("\n"));
}

int Converter::_set_dict_info() {
    wxString line;
    
    int ret = 0;
    while( ret != -1 ) {
        ret = _read_line(line);
        
        if (1==ret) { // empty line
            continue;
        } 
        
        if (0==ret) { // info line
            if (wxNOT_FOUND!=line.Find(_T("<dictinfo>"))) { // info start
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#bookname"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                dictname = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#author"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                author = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#email"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                email = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#version"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                version = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#website"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                website = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#license"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                license = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#origLang"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                origLang = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#destLang"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                destLang = line.Mid(index+1);
                continue;
            }
            
            if (wxNOT_FOUND!=line.Find(_T("#description"))) {
                int index = line.Find('=');
                
                if (wxNOT_FOUND==index) {
                    continue;
                }
                
                description = line.Mid(index+1);
                continue;
            }

            if (wxNOT_FOUND!=line.Find(_T("</dictinfo>"))) { // info end
                break;
            }
        }
    }
    
    DictInfo dictinfo;
    dictinfo.d_name = dictname;
    dictinfo.d_author = author;
    dictinfo.d_email = email;
    dictinfo.d_website = website;
    dictinfo.d_version = version;
    dictinfo.d_license = license;
    dictinfo.d_description = description;
    dictinfo.d_origlang = origLang;
    dictinfo.d_destlang = destLang;
    
    d_id = _dictdb_utils.add_dict_info(dictinfo);
    
    if (-1==d_id) {
        wxLogFatalError(_T("Dictionary with same name (%s) already exist."), 
                dictname.c_str());
    }
    if (d_id<-1) {
        wxLogFatalError(_T("Error when add dict info to .daodict."));
    }
    
    return 0;
}

int Converter::_read_line(wxString& line) {
    if (_txtfile.Eof()) {
        return -1;
    }
    
    memset(buffer, 0, sizeof(buffer));
    char* p_buf = buffer;
    
    // read first char of new line
    _txtfile.Read(p_buf, 1);
    if ('\r'==p_buf[0]||'\n'==p_buf[0]) {
        return 1;
    }
    p_buf = p_buf + 1;
    
    // read next
    while ( !_txtfile.Eof() ) {
        _txtfile.Read(p_buf, 1);
        
        if ('\r'==p_buf[0]||'\n'==p_buf[0]) {
            p_buf[0] = '\0';
            line = wxString(buffer, wxConvUTF8);
            break;
        }
        
        p_buf = p_buf + 1;
    }
    
    return 0;
}

bool Converter::_add_word_to_dictdb(const wxString& str) {
    int index = str.Find('\t');
    
    if (index==wxNOT_FOUND) {
        wxLogError(_T("Can't find \'\\t\' when adding word NO. %d : %s"), 
                _converted_words, str.c_str());
        return false;
    }
    
    if (index==0) {
        wxLogError(_T("Only find word explanation when adding word NO. %d : %s"), 
                _converted_words, str.c_str());
    }
    
    if (index==(str.Len()-1)) {
        wxLogError(_T("Can't find word explanation when adding word NO. %d : %s"), 
                _converted_words, str.c_str());
        return false;
    }
    
    wxString word = str.Mid(0,index);
    wxString expl = str.Mid(index+1);
    // wxPrintf(word+'\t'+expl+'\n');
    
    if (d_id<0) {
        return false;
    }
    
    _dictdb_utils.add_word_to_dict(d_id, word, expl);
    return true;
}
